﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace ServiceTester {
    using System.Diagnostics;
    using System.IO;

    using ServiceTester.ServerRentIt11;

    public partial class frmImdbMovie : Form {
        public string movieId = "";

        private ImdbMovieEntry entry;

        private UserSession uSession;
        private RentItClient rClient;

        private Dictionary<string, GenreEntry> availGenres = new Dictionary<string, GenreEntry>();
        private HashSet<String> genres = new HashSet<string>();

        public frmImdbMovie(frmAdmin fromAdmin, string movieId) {
            if (fromAdmin != null) {
                InitializeComponent();
                uSession = fromAdmin.uSession;
                rClient = fromAdmin.rClient;
                this.movieId = movieId;
            } else {
                throw new ArgumentException("A Admin Client Form must be specified!");
            }
        }

        private void frmImdbMovie_FormClosing(object sender, FormClosingEventArgs e) {
            try {
                if(picThumb.Image != null) picThumb.Image.Dispose();
            } catch {}
        }

        private void frmImdbMovie_Load(object sender, EventArgs e) {
            this.GetGenres();
            this.GetParentalGuidance();
            this.GetInfo();
        }

        private void GetInfo() {
            entry = rClient.GetImdbMovie(movieId);
            this.Text = "IMDB Movie Info: " + entry.Title;
            txtId.Text = "" + entry.ImdbId;
            txtTitle.Text = entry.Title;
            numYear.Value = entry.Year;
            numLength.Value = entry.Length;
            txtLanguage.Text = entry.Language;
            cmbParentalGuidance.Text = entry.ParentalGuidance.ToString();
            txtRelease.Text = entry.ReleaseDate.ToString("yyyy-MM-dd");
            txtSummary.Text = entry.Summary;

            lstGenre.Items.Clear();
            genres.Clear();
            foreach (var genre in entry.Genre) {
                genres.Add(genre.Name);
                lstGenre.Items.Add(genre.Name);
            }

            var ms = new MemoryStream(entry.ThumbData);
            try { picThumb.Image = Image.FromStream(ms); }
            catch (Exception ex) {
                Console.Write(ex);
            }
        }

        private void GetGenres() {
            var genres = rClient.ListGenres();
            cmbAvailableGenres.Items.Clear();

            foreach (var genre in genres) {
                availGenres[genre.Name] = genre;
                cmbAvailableGenres.Items.Add(genre.Name);
            }

            if (cmbAvailableGenres.Items.Count > 0) cmbAvailableGenres.SelectedIndex = 0;
        }

        private void GetParentalGuidance() {
            cmbParentalGuidance.Items.Clear();

            foreach(var enumVal in Enum.GetNames(typeof(ParentalGuidance))) {
                if(enumVal != "Ignore") cmbParentalGuidance.Items.Add(enumVal);
            }

            if(cmbParentalGuidance.Items.Count > 0) cmbParentalGuidance.SelectedIndex = 0;
        }

        private void btnClose_Click(object sender, EventArgs e) {
            this.Close();
        }

        private void btnSave_Click(object sender, EventArgs e) {
            btnSave.Enabled = false;

            if (uSession != null && uSession.UserId > 0 && uSession.IsAdmin) {
                var mEntry = new MovieEntry
                    {
                        Title = this.txtTitle.Text,
                        Year = (int)this.numYear.Value,
                        Length = (int)this.numLength.Value,
                        Language = this.txtLanguage.Text,
                        ParentalGuidance = rClient.GetParentalGuidance(this.cmbParentalGuidance.Text),
                        HighDefinition = (this.rdbHDYes.Checked ? XBool.True : XBool.False),
                        ImdbId = movieId
                    };

                var rday = DateTime.MinValue;
                DateTime.TryParse(txtRelease.Text, out rday);
                mEntry.ReleaseDate = rday;

                mEntry.Summary = txtSummary.Text;

                var res = rClient.InsertMovie(uSession, mEntry);

                if (res > 0) {
                    if (!UploadThumb(res) || !SaveGenres(res)) res = 0;
                }

                MessageBox.Show(
                    res > 0 ? "Movie saved successfully!" : "Failed to save movie!",
                    "Save Result",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                //if (res) btnRefresh.PerformClick();
            } else {
                MessageBox.Show(
                    "You have to be logged in to an admin account if you wish to save movies!",
                    "Admin Login Required",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }

            btnSave.Enabled = true;
            btnSave.Focus();
        }

        private void btnAddGenre_Click(object sender, EventArgs e) {
            var genreId = availGenres.ContainsKey(cmbAvailableGenres.Text)
                              ? availGenres[cmbAvailableGenres.Text].Id
                              : -1;

            if (genreId > -1 && !genres.Contains(cmbAvailableGenres.Text)) {
                genres.Add(cmbAvailableGenres.Text);
                lstGenre.Items.Add(cmbAvailableGenres.Text);
            }
        }

        private void btnRemoveSelectedGenre_Click(object sender, EventArgs e) {
            if (genres.Contains(cmbAvailableGenres.Text)) {
                lstGenre.Items.Remove(cmbAvailableGenres.Text);
                genres.Remove(cmbAvailableGenres.Text);
            }
        }

        private bool UploadThumb(int dbId) {
            var thumbFileName = "thumb_" + Environment.TickCount + "_" + movieId + ".jpg";
            picThumb.Image.Save(thumbFileName);

            if (File.Exists(thumbFileName)) {
                var fi = new FileInfo(thumbFileName);
                var uInfo = new UploadFileInfo();
                var res = false;
                uInfo.Admin = uSession;
                uInfo.MovieId = dbId;
                uInfo.Filename = fi.Name;
                uInfo.Size = fi.Length;
                using (var fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    uInfo.FileByteStream = fs;
                    res = rClient.UploadMovieThumb(uInfo.Admin, uInfo.Filename, false, uInfo.MovieId, uInfo.Size,
                                                   uInfo.FileByteStream);
                }

                File.Delete(thumbFileName);

                if (res) {
                    return true;
                }
            }
            return false;
        }

        private bool SaveGenres(int dbId) {
            var toAdd = (from object genre in this.lstGenre.Items
                         select this.availGenres[genre.ToString()]).ToList();

            var res = toAdd.Aggregate(true, (current, genre) => current & this.rClient.AddMovieGenre(uSession, dbId, genre.Id));
            return res;
        }

        public static bool ValidIMDBId(string id) {
            return Regex.IsMatch(id, "^tt[0-9]+$");
        }
    }
}
